package server

import (
	"io"
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"svcfwin/config"
	"svcfwin/log"
	"svcfwin/svc"
	"syscall"
	// 导入 logrus 库
)

const (
	RestartServerUrl      = "/service/restart" // put
	QueryServiceStatusUrl = "/service/query"   // get
	StartServiceUrl       = "/service/start"   // put
	StopServiceUrl        = "/service/stop"    // put
	UpdateConfigUrl       = "/file/update"     // post
	FileQueryUrl          = "/file/query"      // get
)

// 启动服务监听
func StartListener(port int) {
	log.Log.Info("启动服务中......")

	mux := http.NewServeMux()
	mux.HandleFunc(RestartServerUrl, RestartServerHandler)
	mux.HandleFunc(QueryServiceStatusUrl, QueryServiceStatusHandler)
	mux.HandleFunc(StartServiceUrl, StartServiceHandler)
	mux.HandleFunc(StopServiceUrl, StopServiceHandler)
	mux.HandleFunc(UpdateConfigUrl, UpdateConfigHandler)
	mux.HandleFunc(FileQueryUrl, FileQueryHandler)

	server := &http.Server{
		Addr:    ":" + strconv.Itoa(port), // 将端口转换为字符串
		Handler: mux,
	}

	go func() {
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Log.Fatalf("ListenAndServe error on %s: %v", server.Addr, err)
			os.Exit(1)
		}
	}()

	log.Log.Infof("服务已启动，监听端口: %d", port)

	// 捕获系统信号以优雅关闭服务
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)

	<-sigChan // 阻塞等待信号
	log.Log.Info("收到终止信号，正在关闭服务...")

	if err := server.Close(); err != nil {
		log.Log.Errorf("关闭服务时发生错误: %v", err)
	}
}

// 判断请求方法
func checkMethod(w http.ResponseWriter, r *http.Request, method string) bool {
	if r.Method != method {
		w.WriteHeader(http.StatusMethodNotAllowed)
		w.Write([]byte("Method not allowed"))
		return false
	}
	return true
}

// 认证校验
func IsAuth(w http.ResponseWriter, r *http.Request) bool {
	// 读取请求指定请头内容并进行判断
	if r.Header.Get("Auth-Token") != config.Config.Auth.Token {
		log.Log.Errorf("认证失败")
		w.WriteHeader(http.StatusUnauthorized)
		w.Write([]byte("认证失败"))
		return false
	}
	log.Log.Infof("认证成功")
	return true
}

// 重启服务
func RestartServerHandler(w http.ResponseWriter, r *http.Request) {
	if !checkMethod(w, r, "PUT") {
		return
	}
	if !IsAuth(w, r) {
		return
	}
	log.Log.Infof("重启服务: %s", config.Config.Service.Name)
	if err := svc.RestartService(config.Config.Service.Name); err != nil {
		log.Log.Errorf("服务重启失败: %s", err)
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("服务重启失败"))
		return
	}
	log.Log.Infof("服务重启成功")
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("服务重启成功"))
}

func QueryServiceStatusHandler(w http.ResponseWriter, r *http.Request) {
	if !checkMethod(w, r, "GET") {
		return
	}
	if !IsAuth(w, r) {
		return
	}
	svcName := config.Config.Service.Name
	log.Log.Infof("查询服务: %s", svcName)
	statusString, err := svc.QueryService(svcName)
	if err != nil {
		log.Log.Errorf("服务查询失败: %s", err)
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("服务查询失败"))
		return
	}
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(statusString))
}

func StartServiceHandler(w http.ResponseWriter, r *http.Request) {
	if !checkMethod(w, r, "PUT") {
		return
	}
	if !IsAuth(w, r) {
		return
	}
	svcName := config.Config.Service.Name
	log.Log.Infof("启动服务: %s", svcName)
	err := svc.StartService(svcName)
	if err != nil {
		log.Log.Errorf("启动服务失败: %s", err)
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("启动服务失败"))
	}
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("启动服务成功"))
}

func StopServiceHandler(w http.ResponseWriter, r *http.Request) {
	if !checkMethod(w, r, "PUT") {
		return
	}
	if !IsAuth(w, r) {
		return
	}
	svcName := config.Config.Service.Name
	log.Log.Infof("停止服务: %s", svcName)
	err := svc.StopService(svcName)
	if err != nil {
		log.Log.Errorf("关闭服务失败: %s", err)
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("关闭服务失败"))
	}
	log.Log.Infof("服务已停止: %s", svcName)
	w.Write([]byte("服务已停止"))
}

func UpdateConfigHandler(w http.ResponseWriter, r *http.Request) {
	if !checkMethod(w, r, "POST") {
		return
	}
	if !IsAuth(w, r) {
		return
	}
	// 读取请求体中的配置数据
	// 解析配置数据，更新全局变量Config
	configContentByte, err := io.ReadAll(r.Body)
	if err != nil {
		log.Log.Errorf("读取更新内容失败: %s", err)
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("更新文件失败"))
		return
	}
	configContent := string(configContentByte)
	log.Log.Infof("更新文件内容: %s", configContent)
	filepath := config.Config.File.Path
	log.Log.Infof("打开文件: %s", filepath)
	filefd, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		log.Log.Errorf("打开文件失败: %s", err)
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("文件更新失败"))
		return
	}
	defer filefd.Close()
	_, err = io.WriteString(filefd, configContent)
	if err != nil {
		log.Log.Errorf("文件更新失败: %s", err)
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("文件更新失败"))
		return
	}
	log.Log.Infof("文件更新成功")
	// 响应客户端
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("文件更新成功"))
}

func FileQueryHandler(w http.ResponseWriter, r *http.Request) {
	if !checkMethod(w, r, "GET") {
		return
	}
	if !IsAuth(w, r) {
		return
	}
	// 读取文件内容
	filePath := config.Config.File.Path
	log.Log.Infof("读取文件: %s", filePath)
	fileContent, err := os.ReadFile(filePath)
	if err != nil {
		log.Log.Errorf("读取文件 %s 失败", err)
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("Failed to read file"))
		return
	}
	w.WriteHeader(http.StatusOK)
	w.Write(fileContent)
}
